﻿using System;
using System.Collections;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;

using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.FEZ;

namespace CobraController
{
  public class Program
  {
    static InterruptPort up;
    static InterruptPort select;
    static InterruptPort down;
    static InterruptPort hall;
    static OutputPort led;
    static bool open = false;
    static SerialComm sc;
		static OWSensors ows = new OWSensors(FEZ_Pin.Digital.IO15);

    public static void Main()
    {

      Settings.DomoticaServerIP = "10.0.10.92";
      Settings.DomoticaServerPort = 13000;
      Settings.CobraSocketPort = 12000;
      Settings.CommPort = "COM4";
      Settings.CommPortSpeed = 115200;
      Settings.CommDelimiter = 10; // \r\n
      Settings.HostID = "COBRA";
      MessageEventHandler.MessageEvent += new NewMessageEventHandler(MessageEventHandler_MessageEvent);

      SDLogger.start();



      Cpu.GlitchFilterTime = new TimeSpan(0, 0, 0, 0, 900);
      RealTimeClock.SetTime(NtpClient.GetNetworkTime());
      Utility.SetLocalTime(RealTimeClock.GetTime());
      Debug.Print("Time now is: " + DateTime.Now.ToString());
      //Timer MyTimer = new Timer(new TimerCallback(RunMe), null, 10000, 10000);
      up = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.ButtonUp, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);
      select = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.ButtonSelect, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);
      down = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.ButtonDown, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);

      hall = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.IO23, false, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);

      led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, false);

      hall.OnInterrupt += new NativeEventHandler(hall_OnInterrupt);

      up.OnInterrupt += new NativeEventHandler(up_OnInterrupt);
      select.OnInterrupt += new NativeEventHandler(select_OnInterrupt);
      down.OnInterrupt += new NativeEventHandler(down_OnInterrupt);

      sc = new SerialComm();
      sc.Open();

      SocketServer socketserver = new SocketServer();


      Thread.Sleep(Timeout.Infinite);


    }

    static void MessageEventHandler_MessageEvent(object sender, MessageEventArgs se)
    {
      //Debug.Print(Debug.GC(false).ToString());
      string msg = se.LatestMessage.ToLower();
      //Debug.Print("Event: " + msg);
      MTS mts = MessageHandler.ParseMessage(msg);
      //if (mts.MyTransport == Transport.NET)
      //  { 
      //  SocketClient.Send(mts.MyMessage.ToString());
      //  Debug.Print("Transport is NET");
      //  }
      //if (mts.MyTransport == Transport.SER)
      //  { 
      //  sc.Send(mts.MyMessage.ToString());
      //  Debug.Print("Transport is SER");
      //  }
      //if (mts.MyTransport == Transport.LOC)
      //{ 
      //  ProcessLocal(mts.MyMessage);
      //  Debug.Print("Transport is LOC");
      //}

      switch (mts.MyTransport)
      {
        case Transport.NET:
          //Debug.Print("Transport is NET");
          SocketClient.Send(mts.MyMessage.ToString());
          break;
        case Transport.SER:
          //Debug.Print("Transport is SER");
          sc.Send(mts.MyMessage.ToString());
          break;
        case Transport.LOC:
          //Debug.Print("Transport is LOC");
          ProcessLocal(mts.MyMessage);
          break;
        default:
          //Debug.Print("No Transport match");
          break;
      }
    }

    static void ProcessLocal(Message msg)
    {
			if (msg.Command == Command.GetSensorValues)
			{
				ArrayList sensorvalues = ows.GetSensorValues();
				foreach (SensorData sd in sensorvalues)
				{
					Message mes = new Message();
					mes.SenderID = ID.COBRA;
					mes.TargetID = ID.HAMS;
					mes.Command = "sensorvalue";
					mes.ParamsCount = 4;
					mes.Params = new string[4];
					mes.Params[0] = sd.sensorAddress;
					mes.Params[1] = sd.sensorModel;
					mes.Params[2] = sd.sensorType;
					mes.Params[3] = sd.sensorValue.ToString();
					SocketClient.Send(mes.ToString());
					Thread.Sleep(50);
				}
				sensorvalues.Clear();
			}
    }

    static void hall_OnInterrupt(uint data1, uint data2, DateTime time)
    {
      Message msg = new Message();
      msg.SenderID = ID.COBRA;
      msg.TargetID = ID.HAMS;
      msg.Command = Command.GarageState;
      msg.ParamsCount = 1;
      msg.Params = new string[1];

      if (data2 == 0)
      {
        led.Write(true);
        msg.Params[0] = Garage.Open;
      }
      else
      {
        led.Write(false);
        msg.Params[0] = Garage.Closed;
      }
      SocketClient.Send(msg.ToString());
    }

    static void down_OnInterrupt(uint data1, uint data2, DateTime time)
    {
      Message msg = new Message();
      msg.SenderID = ID.COBRA;
      msg.TargetID = ID.HAMS;
      msg.Command = Command.GarageState;
      msg.ParamsCount = 1;
      msg.Params[0] = Garage.Open;
      SocketClient.Send(msg.ToString());
    }

    static void select_OnInterrupt(uint data1, uint data2, DateTime time)
    {
      SocketClient.Send("Select button pressed");
    }

    static void up_OnInterrupt(uint data1, uint data2, DateTime time)
    {
      Message msg = new Message();
      msg.SenderID = ID.COBRA;
      msg.TargetID = ID.PANDA;
      msg.Command = Command.GetCounters;
      msg.ParamsCount = 0;
      sc.Send(msg.ToString());
    }

    static void RunMe(object o)
    {
      //Debug.Print("Timer fired");
      //SocketClient.Send("Garage door opened");
      //Debug.Print("Message sent");

      if (open)
      {
        SocketClient.Send("Garage door opened");
        open = false;
      }
      else
      {
        SocketClient.Send("Garage door closed");
        open = true;
      }
    }





  }
}
